package com.xdqzy.baseline.common.config;

import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author : zhangdongdong
 * @version V1.0
 * @Title : rest配置
 * @ClassName: com.xdqzy.baseline.common.config.RestConfig.java
 * @Description:
 * @date :  2020-10-20 17:14
 */
@Configuration
public class RestConfig {
    private static final int SOCKET_TIME_OUT = 10000;

    private static final int REQUEST_TIME_OUT = SOCKET_TIME_OUT / 2;

    @Bean
    public RestTemplate restTemplate() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient()));
        HttpMessageConverter<?> converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
        List<HttpMessageConverter<?>> convertList = new ArrayList<>();
        convertList.add(converter);
        MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
        List<MediaType> asList = new ArrayList<>();
        asList.add(MediaType.APPLICATION_JSON);
        asList.add(MediaType.TEXT_PLAIN);
        asList.add(MediaType.APPLICATION_JSON_UTF8);
        jackson2HttpMessageConverter.setSupportedMediaTypes(asList);
        convertList.add(jackson2HttpMessageConverter);
        template.setMessageConverters(convertList);
        return template;
    }


    private HttpClient httpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        SSLContext sslcontext =
                SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
        SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
                sslcontext, new String[]{"TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE);

        Registry<ConnectionSocketFactory> socketFactoryRegistry =
                RegistryBuilder.<ConnectionSocketFactory>create()
                        .register("http", PlainConnectionSocketFactory.getSocketFactory())
                        .register("https", sslConnectionSocketFactory).build();

        // 5秒超时
        RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(REQUEST_TIME_OUT)
                .setSocketTimeout(SOCKET_TIME_OUT).setConnectTimeout(SOCKET_TIME_OUT).build();
        SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(REQUEST_TIME_OUT).setSoKeepAlive(true).build();
        PoolingHttpClientConnectionManager cm =
                new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        cm.setMaxTotal(32);
        // 单路由最大并发数
        cm.setDefaultMaxPerRoute(32);
        return HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .setDefaultSocketConfig(socketConfig).setConnectionManager(cm).build();
    }


}
